package com.ht.demo.service.aspect;

import com.ht.demo.common.appexception.AppErrorCodeEnum;
import com.ht.demo.common.pojo.bo.system.SysUserBO;
import com.ht.demo.dao.dao.system.SysRoleMenuDao;
import com.ht.demo.dao.dao.system.SysUserRoleDao;
import com.ht.demo.dao.domain.system.SysUserRoleDO;
import com.ht.demo.service.annotation.Permission;
import com.ht.demo.common.appexception.AppException;
import com.ht.demo.service.system.UserTokenManager;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @Author hdengxian
 * @Date 2023/4/10 9:06
 */
@Aspect
@Component
public class PermissionAspect {
    Logger logger = LoggerFactory.getLogger(PermissionAspect.class);
    @Resource
    private SysRoleMenuDao sysRoleMenuDao;
    @Resource
    private SysUserRoleDao sysUserRoleDao;
    /**
     * 切入点定义在此annotation上
     */
    @Pointcut("@annotation(com.ht.demo.service.annotation.Permission)")
    private void getPermissionAopPointcut(){}

    @Before("@annotation(permission)")
    public void doPermissionBefore(Permission permission) throws AppException {
        // 当前登录用户,当前请求用户
        SysUserBO loginUser = UserTokenManager.getInstance().getLoginUser();
        if (SysUserBO.isAdmin(loginUser.getSysUserId())) {
            //如果时超级管理员，不校验权限
            return;
        }
        //权限标识
        String permissionId = permission.permissionId();
        //权限说明
        String desc = permission.desc();
        //原本可以直接从redis中取用户角色信息，但是如果用户的角色被更改了，则取到的角色将是错误的
        //如果需要改变此情况，则需要改造更改用户角色接口，想办法将更新后的角色信息同步至redis，
        //这里我暂时没时间去想，这样写也没有什么影响
        SysUserRoleDO userRoleDO = sysUserRoleDao.findByUserId(loginUser.getSysUserId());
        Integer count = sysRoleMenuDao.countPermission(permissionId, userRoleDO.getSysRoleId());
        if (count == null || count <= 0) {
            logger.error("PermissionAspect.doPermissionBefore - 用户【{}】权限不足，需要权限标识：【{}】", loginUser.getUserName(), permissionId);
            throw new AppException(AppErrorCodeEnum.NO_PERMISSION);
        }
    }

}
